import { TaskBase } from './TaskBase';
import { deserializeTask } from './taskmap';
import { TaskTypes } from './impl/types';

const __makeProto = (
    name: string, target: CreepTargettableObject, data?: TaskDataRecorder
): TaskBase => {
    return deserializeTask({
        name,
        target: {
            id: target.id,
            pos: target.pos
        },
        data
    });
};

export type ObjectWithStore =
    | AnyStoreStructure
    | AnyCreep;

export class Tasks {

    static build(site: ConstructionSite) {
        return __makeProto(TaskTypes.build, site);
    }

    static claim(controller: StructureController) {
        return __makeProto(TaskTypes.claim, controller);
    }

    static dismantle(target: Structure<BuildableStructureConstant>) {
        return __makeProto(TaskTypes.dismantle, target);
    }

    static fortify(barrier: StructureRampart | StructureWall, limit?: number) {
        return __makeProto(TaskTypes.fortify, barrier, { amount: limit });
    }

    static getBoosted(lab: StructureLab, resource: MineralCompoundConstant, num: number) {
        return __makeProto(TaskTypes.getBoosted, lab, { rType: resource, amount: num });
    }

    static getRenewed(spawn: StructureSpawn) {
        return __makeProto(TaskTypes.getRenewed, spawn);
    }

    static harvest(object: Source | Mineral | Deposit) {
        return __makeProto(TaskTypes.harvest, object);
    }

    static invalid(): SerializedTaskObject {
        return { name: TaskTypes.invalid, target: {} };
    }

    static pickup(resource: Resource) {
        return __makeProto(TaskTypes.pickup, resource);
    }

    static repair(target: Structure) {
        return __makeProto(TaskTypes.repair, target);
    }

    static reserve(controller: StructureController) {
        return __makeProto(TaskTypes.reserve, controller);
    }

    static transfer(target: ObjectWithStore, rType: ResourceConstant, amount?: number) {
        return __makeProto(TaskTypes.transfer, target, { rType, amount });
    }

    static transferAll(target: ObjectWithStore, skipResource?: ResourceConstant) {
        return __makeProto(TaskTypes.transferAll, target, { rType: skipResource });
    }

    static upgrade(controller: StructureController) {
        return __makeProto(TaskTypes.upgrade, controller);
    }

    static withdraw(target: ObjectWithStore, rType: ResourceConstant, amount?: number) {
        return __makeProto(TaskTypes.withdraw, target, { rType, amount });
    }

    static withdrawAll(target: ObjectWithStore, skipResource?: ResourceConstant) {
        return __makeProto(TaskTypes.withdrawAll, target, { rType: skipResource });
    }

}